package com.carHailing.gateway.filters;

import com.carHailing.common.constants.JwtConstants;
import com.carHailing.common.constants.TokenConstants;
import com.carHailing.common.redis.RedisCache;
import com.carHailing.common.utils.JwtUtils;
import com.carHailing.common.utils.StringUtils;
import com.carHailing.gateway.config.IgnoreWhiteConfig;
import com.carHailing.gateway.utils.GatewayUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;

/**
 * @Author YanShuLing
 * @Package:com.bw.gateway.filter
 * @Project: nacos-day4
 * @name:LoginFilter
 * @Date 2023/12/13:15:36
 */

@Component
@Slf4j
public class LoginFilter implements GlobalFilter, Ordered {

/**
 *@ClassName LoginFilter
 *@Description 描述
 *@Author ShuLing.Yan
 *@Date 2023/12/13 :15:36
 */

   private final IgnoreWhiteConfig ignoreWhiteConfig;

   private final RedisCache redisCache;


    public LoginFilter(IgnoreWhiteConfig ignoreWhiteConfig, RedisCache redisCache) {
        this.ignoreWhiteConfig = ignoreWhiteConfig; //redis操作
        this.redisCache = redisCache; //白名单
    }


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {


        //请求作用域
        ServerHttpRequest request = exchange.getRequest();
        //请求头
        HttpHeaders headers = request.getHeaders();
        //请求方式
        HttpMethod method = request.getMethod();
         //header操作对象
        ServerHttpRequest.Builder mutate = request.mutate();


        String requestURI = request.getURI().getPath();
        log.info("请求日志：url:[{}],请求方式:[{}]",requestURI,method);

        List<String> whites = ignoreWhiteConfig.getWhites();

        if(StringUtils.matches(requestURI,whites)){
            return chain.filter(exchange);
        }

        String token = headers.getFirst("token");

        if(StringUtils.isEmpty(token)){
            return GatewayUtils.errorResponse(exchange,"令牌不能为空");
        }

        Claims claims = JwtUtils.parseToken(token);

        if(claims==null){
            return GatewayUtils.errorResponse(exchange,"令牌已经过期");
        }

        String userKey = JwtUtils.getUserKey(claims);

        Boolean isLogin = redisCache.hasKey(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        if(!isLogin){
            return GatewayUtils.errorResponse(exchange,"登录已经过期");
        }



        long expire = redisCache.getExpire(TokenConstants.LOGIN_TOKEN_KEY + userKey);

        long initExpire = 5*60*1000;

        if(expire<(initExpire/2)){
            redisCache.expire(TokenConstants.LOGIN_TOKEN_KEY+userKey,5,TimeUnit.MINUTES);
        }

        String userid = JwtUtils.getUserId(claims);

        String username = JwtUtils.getUserName(claims);
        // 设置用户信息到请求
        GatewayUtils.addHeader(mutate, JwtConstants.USER_KEY, userKey);

        GatewayUtils.addHeader(mutate, JwtConstants.DETAILS_USER_ID, userid);

        GatewayUtils.addHeader(mutate, JwtConstants.DETAILS_USERNAME, username);
        // 内部请求来源参数清除
        GatewayUtils.removeHeader(mutate, TokenConstants.TOKEN);


        return chain.filter(exchange.mutate().request(mutate.build()).build());
    }


    @Override
    public int getOrder() {
        return 0;
    }
}
